#ifndef WEBSERVER_H
#define WEBSERVER_H 1

#include <zlib.h>
#include "mfc.h"
#include "WebSocket.h"
#include "PartFile.h"

#define WEB_GRAPH_HEIGHT		120
#define WEB_GRAPH_WIDTH			500

#define SESSION_TIMEOUT_SECS	300	// 5 minutes session expiration
#define SHORT_FILENAME_LENGTH	40	// Max size of file name.

typedef struct { float download; float upload; } UpDown;

typedef struct { time_t startTime; long lSession; bool admin;} Session;

typedef struct
{
	wxString	sFileName;
	wxString	sFileStatus;
	long	lFileSize;
	long	lFileTransferred;
	long	lFileSpeed;
	long	lSourceCount;
	long	lNotCurrentSourceCount;
	long	lTransferringSourceCount;
	int		nFileStatus;
	wxString	sFileHash;
	wxString	sED2kLink;
	wxString	sFileInfo;
} DownloadFiles;

typedef struct
{
	wxString	sFileName;
	long	lFileSize;
	uint32	nFileTransferred;
    uint64	nFileAllTimeTransferred;
	uint16	nFileRequests;
	uint32	nFileAllTimeRequests;
	uint16	nFileAccepts;
	uint32	nFileAllTimeAccepts;
	uint8	nFilePriority;
	wxString sFilePriority;
	bool	bFileAutoPriority;
	wxString sFileHash;
	wxString	sED2kLink;
} SharedFiles;

typedef enum
{
	DOWN_SORT_NAME,
	DOWN_SORT_SIZE,
	DOWN_SORT_TRANSFERRED,
	DOWN_SORT_SPEED,
	DOWN_SORT_PROGRESS
} xDownloadSort;

typedef enum
{
	SHARED_SORT_NAME,
	SHARED_SORT_SIZE,
	SHARED_SORT_TRANSFERRED,
	SHARED_SORT_ALL_TIME_TRANSFERRED,
	SHARED_SORT_REQUESTS,
	SHARED_SORT_ALL_TIME_REQUESTS,
	SHARED_SORT_ACCEPTS,
    SHARED_SORT_ALL_TIME_ACCEPTS,
	SHARED_SORT_PRIORITY
} xSharedSort;

typedef struct
{
	wxString	sServerName;
	wxString	sServerDescription;
	int		nServerPort;
	wxString	sServerIP;
	int		nServerUsers;
	int		nServerMaxUsers;
	int		nServerFiles;
} ServerEntry;

typedef enum
{
	SERVER_SORT_NAME,
	SERVER_SORT_DESCRIPTION,
	SERVER_SORT_IP,
	SERVER_SORT_USERS,
	SERVER_SORT_FILES
} xServerSort;

typedef struct
{
	uint32			nUsers;
	xDownloadSort	DownloadSort;
	bool			bDownloadSortReverse;
	xServerSort		ServerSort;
	bool			bServerSortReverse;
	xSharedSort		SharedSort;
	bool			bSharedSortReverse;	
	bool			bShowUploadQueue;

	CArray<UpDown*, UpDown*>		PointsForWeb;
	CArray<Session*, Session*>	Sessions;
} GlobalParams;

typedef struct
{
	wxString			sURL;
	void			*pThis;
	CWebSocket		*pSocket;
} ThreadData;

typedef struct
{
	wxString	sHeader;
	wxString	sHeaderMetaRefresh;
	wxString	sHeaderStylesheet;
	wxString	sFooter;
	wxString	sServerList;
	wxString	sServerLine;
	wxString	sTransferImages;
	wxString	sTransferList;
	wxString	sTransferDownHeader;
	wxString	sTransferDownFooter;
	wxString	sTransferDownLine;
	wxString	sTransferDownLineGood;
	wxString	sTransferUpHeader;
	wxString	sTransferUpFooter;
	wxString	sTransferUpLine;
	wxString	sTransferUpQueueShow;
	wxString	sTransferUpQueueHide;
	wxString	sTransferUpQueueLine;
	wxString	sTransferBadLink;
	wxString	sDownloadLink;
	wxString	sSharedList;
	wxString	sSharedLine;
	wxString	sSharedLineChanged;
	wxString	sGraphs;
	wxString	sLog;
	wxString	sServerInfo;
	wxString sDebugLog;
	wxString sStats;
	wxString sPreferences;
	wxString	sLogin;
	wxString	sConnectedServer;
	wxString	sAddServerBox;
	wxString	sWebSearch;
	wxString	sResDir;
	uint16	iProgressbarWidth;
} WebTemplates;

class CWebServer
{
	friend class CWebSocket;

public:
	CWebServer(void);
	~CWebServer(void);

	int	 UpdateSessionCount();
	void StartServer(void);
	void AddStatsLine(UpDown* line);
	void ReloadTemplates();
	uint16	GetSessionCount()	{ return m_Params.Sessions.GetCount();}
	bool IsRunning()	{ return m_bServerWorking;}

protected:
	static void		ProcessURL(ThreadData);
	static void 	ProcessImgFileReq(ThreadData);
	
private:
	static wxString	_GetHeader(ThreadData, long lSession);
	static wxString	_GetFooter(ThreadData);
	static wxString _GetSearch(ThreadData);
	static wxString	_GetServerList(ThreadData);
	static wxString	_GetTransferList(ThreadData);
	static wxString	_GetDownloadLink(ThreadData);
	static wxString	_GetSharedFilesList(ThreadData);
	static wxString	_GetGraphs(ThreadData);
	static wxString	_GetLog(ThreadData);
	static wxString	_GetServerInfo(ThreadData);
	static wxString	_GetDebugLog(ThreadData);
	static wxString	_GetStats(ThreadData);
	static wxString	_GetPreferences(ThreadData);
	static wxString	_GetLoginScreen(ThreadData);
	static wxString	_GetConnectedServer(ThreadData);
	static wxString 	_GetAddServerBox(ThreadData Data);
	static void		_RemoveServer(wxString sIP);
    static wxString	_GetWebSearch(ThreadData Data);

	static wxString	_ParseURL(wxString URL, wxString fieldname); 

	static void		_ConnectToServer(wxString sIP);
	static bool		_IsLoggedIn(ThreadData Data, long lSession);
	static void		_RemoveTimeOuts(ThreadData Data, long lSession);
	static bool		_RemoveSession(ThreadData Data, long lSession);
	static bool		_GetFileHash(wxString sHash, uchar *FileHash);
	static wxString	_SpecialChars(wxString str);
	static wxString	_GetPlainResString(UINT nID, bool noquote = false);
	static int		_GzipCompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);
	static void		_SetSharedFilePriority(wxString hash, uint8 priority);
	static wxString	_GetWebCharSet();
	wxString			_LoadTemplate(wxString sAll, wxString sTemplateName);
	static Session	GetSessionByID(ThreadData Data,long sessionID);
	static bool		IsSessionAdmin(ThreadData Data,wxString SsessionID);
	static wxString	GetPermissionDenied();
	static wxString	_GetDownloadGraph(ThreadData Data,wxString filehash);

	// Common data
	GlobalParams	m_Params;
	WebTemplates	m_Templates;
	bool			m_bServerWorking;
};

#endif
